package com.mike.ad.mysql.dto;

import com.mike.ad.mysql.constant.OPType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class ParseTemplate {
    private String database;
    private Map<String, TableTemplate> tableTemplateMap = new HashMap<>();

    public static ParseTemplate parse(Template _template) {
        ParseTemplate template = new ParseTemplate();
        template.setDatabase(_template.getDatabase());
        _template.getTableList().forEach(item -> {
            String name = item.getTableName();
            Integer level = item.getLevel();
            TableTemplate tableTemplate = new TableTemplate();
            tableTemplate.setTableName(name);
            tableTemplate.setLevel(level.toString());
            template.getTableTemplateMap().put(name, tableTemplate);

            Map<OPType, List<String>> opTypeFieldSetMap =
                    tableTemplate.getOpTypeFieldSetMap();
            for (JsonTable.Column column : item.getInsert()) {
                getAndCreateIfNeed(
                        OPType.ADD,
                        opTypeFieldSetMap,
                        ArrayList::new
                ).add(column.getColumn());
            }
            for (JsonTable.Column column : item.getUpdate()) {
                getAndCreateIfNeed(
                  OPType.UPDATE,
                  opTypeFieldSetMap,
                  ArrayList::new
                ).add(column.getColumn());
            }
            for (JsonTable.Column column : item.getDelete()) {
                getAndCreateIfNeed(
                        OPType.DELETE,
                        opTypeFieldSetMap,
                        ArrayList::new
                ).add(column.getColumn());
            }
        });
        return template;
    }

    public static <T, R> R getAndCreateIfNeed(T key, Map<T, R> map,
                                              Supplier<R> factory) {
        return map.computeIfAbsent(key, k ->
            factory.get());
    }
}
